/*
 *Copyright 2021-2023 NERCIS
 *
 *Licensed under the Apache License, Version 2.0 (the "License");
 *you may not use this file except in compliance with the License.
 *You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *Unless required by applicable law or agreed to in writing, software
 *distributed under the License is distributed on an "AS IS" BASIS,
 *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *See the License for the specific language governing permissions and
 *limitations under the License.
 */

package cn.ac.nercis.pes.service.document.report;

import cn.ac.nercis.pes.common.constant.doc.*;
import cn.ac.nercis.pes.common.constant.evaluation.EvaluationConclusion;
import cn.ac.nercis.pes.common.constant.evaluation.EvaluationResult;
import cn.ac.nercis.pes.common.constant.knowledge.AssetClassification;
import cn.ac.nercis.pes.common.constant.knowledge.LayerTarget;
import cn.ac.nercis.pes.common.constant.knowledge.TargetDeepness;
import cn.ac.nercis.pes.common.utils.DataUtils;
import cn.ac.nercis.pes.model.bo.doc.report.evaluation.UnitEvaluationBO;
import cn.ac.nercis.pes.model.bo.doc.report.evaluation.unit.*;
import cn.ac.nercis.pes.model.bo.doc.report.evaluation.unit.conclusion.*;
import cn.ac.nercis.pes.model.bo.doc.report.table.unit.AppDataItemReportBO;
import cn.ac.nercis.pes.model.bo.doc.report.table.unit.AppKeyDataReportBO;
import cn.ac.nercis.pes.model.bo.doc.report.table.unit.UnitEvalReportBO;
import cn.ac.nercis.pes.model.dto.report.AssetEvalResultDTO;
import cn.ac.nercis.pes.model.dto.report.AssetTargetEvalResultDTO;
import cn.ac.nercis.pes.repository.dal.evaluation.AssetRepository;
import cn.ac.nercis.pes.repository.dal.evaluation.EvaluationRecordRepository;
import cn.ac.nercis.pes.repository.dal.evaluation.LayerEvaluationRepository;
import cn.ac.nercis.pes.repository.dal.evaluation.UnitEvaluationRepository;
import cn.ac.nercis.pes.repository.dal.project.SystemTargetRepository;
import cn.ac.nercis.pes.repository.model.evaluation.AssetDO;
import cn.ac.nercis.pes.repository.model.evaluation.EvaluationRecordDO;
import cn.ac.nercis.pes.repository.model.evaluation.LayerEvaluationDO;
import cn.ac.nercis.pes.repository.model.evaluation.UnitEvaluationDO;
import cn.ac.nercis.pes.repository.model.project.SystemDO;
import cn.ac.nercis.pes.repository.model.project.SystemTargetDO;
import cn.ac.nercis.pes.service.utils.AssetUtils;
import cn.ac.nercis.pes.service.utils.CalculateUtils;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 报告单元测评数据服务类
 * @author zpy
 * @version 1.0.0
 */
@Slf4j
@Service
public record ReportUnitEvaluationDataService(SystemTargetRepository systemTargetRepository,
                                              EvaluationRecordRepository evaluationRecordRepository,
                                              UnitEvaluationRepository unitEvaluationRepository,
                                              LayerEvaluationRepository layerEvaluationRepository,
                                              AssetRepository assetRepository) {

    public UnitEvaluationBO getUnitEvaluationData(@NonNull SystemDO systemDO){
        try {
            List<SystemTargetDO> systemTargets = systemTargetRepository.findAllBySystemId(systemDO.getId());
            return UnitEvaluationBO.builder()
                    .securityLevel(systemDO.getSecurityLevel().getName())
                    .phyEnv(getPhyUnitEvaluation(systemTargets))
                    .netCommunication(getNetCommunicationUnitEvaluation(systemTargets))
                    .deviceCompute(getDeviceComputeUnitEvaluation(systemTargets))
                    .appData(getAppDataUnitEvaluation(systemTargets))
                    .manageSystem(getManageSystemUnitEvaluation(systemDO, systemTargets))
                    .personnelManage(getPersonnelManageUnitEvaluation(systemDO, systemTargets))
                    .buildRunning(getBuildRunningUnitEvaluation(systemDO, systemTargets))
                    .handling(getHandlingUnitEvaluation(systemDO, systemTargets))
                    .build();
        } catch (RuntimeException rEx) {
            log.error("{}/getUnitEvaluationData 获取数据出错：{}", this.getClass().getName(), rEx.getMessage());
            throw rEx;
        }
    }

    private SystemTargetDO findLayerTarget(List<SystemTargetDO> systemTargets, LayerTarget layerTarget){
        return systemTargets.stream()
                .filter(st->StringUtils.equals(st.getKmName(),layerTarget.getName())
                        && st.getKmDeepness() == TargetDeepness.LAYER.getDeepness())
                .findFirst().orElse(null);
    }

    private List<SystemTargetDO> findUnitTargets(List<SystemTargetDO> systemTargets, String layerTargetId){
        return systemTargets.stream()
                .filter(st->StringUtils.equals(st.getKmParentId(),layerTargetId))
                .sorted(Comparator.comparingInt(SystemTargetDO::getKmSort))
                .collect(Collectors.toList());
    }

    private String getResultAnalyze(SystemTargetDO layerTarget,List<SystemTargetDO> systemTargets,
                                             List<EvaluationRecordDO> evaluationRecords) {
        List<UnitEvaluationDO> unitEvaluations = unitEvaluationRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId(), layerTarget.getKmTargetId());
        if (CollectionUtils.isEmpty(unitEvaluations)) {
            return getResultAnalyzeByEmpty();
        }
        List<String> unitTargetResultAnalysis = new ArrayList<>();
        AtomicInteger itemNumber = new AtomicInteger(1);
        systemTargets.stream()
                .filter(st -> StringUtils.equals(st.getKmParentId(), layerTarget.getKmTargetId()))
                .sorted(Comparator.comparingInt(SystemTargetDO::getKmSort))
                .forEach(unitTarget -> {
                    var unitConclusion = getUnitEvaluationConclusion(unitTarget,evaluationRecords);
                    unitEvaluations.stream().filter(ue -> StringUtils.equals(unitTarget.getKmTargetId(), ue.getUnitTargetId()))
                            .findFirst()
                            .ifPresent(ue -> unitTargetResultAnalysis.add(getResultAnalyzeContent(
                                    String.format("%d）%s", itemNumber.getAndIncrement(), unitTarget.getKmName()),
                                    ue.getResultAnalysis(),
                                    unitConclusion)));
                });
        DataUtils.findFirst(layerEvaluationRepository.findBySystemIdAndLayerTargetId(layerTarget.getSystemId(), layerTarget.getKmTargetId()))
                .map(LayerEvaluationDO::getResultAnalysis)
                .filter(StringUtils::isNotBlank)
                .ifPresent(unitTargetResultAnalysis::add);
        if (CollectionUtils.isEmpty(unitTargetResultAnalysis)) {
            return getResultAnalyzeByEmpty();
        }
        return String.join("\n", unitTargetResultAnalysis);
    }

    private EvaluationConclusion getUnitEvaluationConclusion(SystemTargetDO unitTarget, List<EvaluationRecordDO> evaluationRecords){
        if(unitTarget.getIsApply()){
            var unitEvaluationRecord = evaluationRecords.stream()
                    .filter(er->StringUtils.equals(er.getUnitTargetId(),unitTarget.getKmTargetId()))
                    .toList();
            return CalculateUtils.getUnitEvalConclusion(unitEvaluationRecord);
        }else{
            return EvaluationConclusion.NOT_APPLICABLE;
        }
    }

    private List<AssetEvalResultDTO> findAssetEvalResult(SystemTargetDO layerTarget, List<SystemTargetDO> systemTargets,
                                                         List<EvaluationRecordDO> evaluationRecords){
        List<SystemTargetDO> unitTargets = findUnitTargets(systemTargets,layerTarget.getKmTargetId());
        if(CollectionUtils.isEmpty(evaluationRecords) || CollectionUtils.isEmpty(unitTargets)){
            return Collections.emptyList();
        }
        //获取测评对象ID列表
        Set<String> assetIds = evaluationRecords.stream()
                .map(er->er.getAsset().getId())
                .collect(Collectors.toSet());
        List<AssetEvalResultDTO> assetEvalResults = new ArrayList<>();
        int number = 1;
        for(String assetId:assetIds){
            assetEvalResults.add(AssetEvalResultDTO.builder()
                    .number(number)
                    .assetName(evaluationRecords.stream()
                            .filter(er->StringUtils.equals(er.getAsset().getId(),assetId))
                            .map(er->er.getAsset().getName())
                            .findFirst().orElse(""))
                    .targetEval(findAssetTargetEvalResult(assetId,evaluationRecords,unitTargets))
                    .build());
            number++;
        }
        return assetEvalResults;
    }

    private String getUnitTargetName(String unitTargetId, List<SystemTargetDO> systemTargets){
        return systemTargets.stream()
                .filter(st->StringUtils.equals(st.getKmTargetId(),unitTargetId))
                .map(SystemTargetDO::getKmName)
                .findFirst()
                .orElse(StringUtils.EMPTY);
    }

    private List<AssetTargetEvalResultDTO> findAssetTargetEvalResult(String assetId, List<EvaluationRecordDO> evaluationRecords,
                                                                     List<SystemTargetDO> unitTargets){
        var assetTargetEvalResults = evaluationRecords.stream()
                .filter(er->StringUtils.equals(er.getAsset().getId(),assetId))
                .map(er->AssetTargetEvalResultDTO.builder()
                        .targetId(er.getUnitTargetId())
                        .targetName(getUnitTargetName(er.getUnitTargetId(),unitTargets))
                        .result(ReportEvaluationResult.fromConclusion(er.getConclusion().getConclusion()))
                        .build())
                .collect(Collectors.toList());
        for(SystemTargetDO unitTarget:unitTargets){
            if(assetTargetEvalResults.stream()
                    .anyMatch(er->StringUtils.equals(er.getTargetName(),unitTarget.getKmName()))){
                continue;
            }
            assetTargetEvalResults.add(AssetTargetEvalResultDTO.builder()
                    .targetId(unitTarget.getKmTargetId())
                    .targetName(unitTarget.getKmName())
                    .result(ReportEvaluationResult.NOT_APPLICABLE)
                    .build());
        }
        return assetTargetEvalResults;
    }

    private String getUnitEvalConclusion(List<AssetEvalResultDTO> assetEvalResults,String unitTargetName,
                                         List<SystemTargetDO> systemTargets,SystemTargetDO layerTarget){
        SystemTargetDO unitTarget = systemTargets.stream()
                .filter(st->StringUtils.equals(st.getKmParentId(),layerTarget.getKmTargetId())
                        && StringUtils.equals(st.getKmName(),unitTargetName))
                .findFirst().orElse(null);
        if(Objects.nonNull(unitTarget) && !unitTarget.getIsApply()){
            return EvaluationResult.NOT_APPLICABLE.getName();
        }
        var assetTargetEvalResults = assetEvalResults.stream()
                .flatMap(er->er.getTargetEval().stream())
                .filter(ter->StringUtils.equals(ter.getTargetName(),unitTargetName))
                .collect(Collectors.toList());
        if(CollectionUtils.isEmpty(assetTargetEvalResults)|| assetTargetEvalResults.size() == getAssetTargetConclusionCount(assetTargetEvalResults,ReportEvaluationResult.NOT_APPLICABLE)){
            return ReportEvaluationResult.NOT_APPLICABLE.getTag();
        }
        //从列表中排除不适用
        var evalResults = assetTargetEvalResults.stream()
                .filter(er->er.getResult()!= ReportEvaluationResult.NOT_APPLICABLE)
                .collect(Collectors.toList());
        long count = evalResults.size();
        if(count == getAssetTargetConclusionCount(evalResults,ReportEvaluationResult.MATCH)){
            return ReportEvaluationResult.MATCH.getTag();
        }else if(count == getAssetTargetConclusionCount(evalResults,ReportEvaluationResult.NOT_MATCH)){
            return ReportEvaluationResult.NOT_MATCH.getTag();
        }else{
            return ReportEvaluationResult.PARTIALLY_MATCH.getTag();
        }
    }

    private static long getAssetTargetConclusionCount(List<AssetTargetEvalResultDTO> assetTargetEvalResults,ReportEvaluationResult result){
        return assetTargetEvalResults.stream()
                .filter(ter->ter.getResult() == result)
                .count();
    }

    private PhyEnvUnitEvalBO getPhyUnitEvaluation(List<SystemTargetDO> systemTargets){
        PhyEnvUnitEvalBO data = new PhyEnvUnitEvalBO();
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.PHY_ENV);
        if(Objects.isNull(layerTarget)){
            data.setTable(getPhyUnitEvalTableByEmpty());
            data.setConclusion(getPhyEnvConclusionByEmpty());
            data.setResultAnalyze("");
            return data;
        }
        var evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        var assetEvalResults = findAssetPhyUnitEvalResult(layerTarget,systemTargets,evaluationRecords);
        data.setTable(getPhyUnitEvalTable(assetEvalResults));
        data.setConclusion(PhyEnvConclusionBO.builder()
                .identification(getUnitEvalConclusion(assetEvalResults,PhyEnvUnitEvalTarget.IDENTIFICATION.getText(),systemTargets,layerTarget))
                .electronic(getUnitEvalConclusion(assetEvalResults,PhyEnvUnitEvalTarget.ELECTRONIC.getText(),systemTargets,layerTarget))
                .video(getUnitEvalConclusion(assetEvalResults,PhyEnvUnitEvalTarget.VIDEO.getText(),systemTargets,layerTarget))
                .build());
        data.setResultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords));
        return data;
    }

    private List<AssetEvalResultDTO> findAssetPhyUnitEvalResult(SystemTargetDO layerTarget,List<SystemTargetDO> systemTargets,
                                                                List<EvaluationRecordDO> evaluationRecords){
        var unitTargets = findUnitTargets(systemTargets,layerTarget.getKmTargetId());
        if(CollectionUtils.isEmpty(evaluationRecords) || CollectionUtils.isEmpty(unitTargets)){
            return Collections.emptyList();
        }
        var assetSource = this.assetRepository.findAllBySystemId(layerTarget.getSystemId());
        //获取测评对象ID列表
        Set<String> assetIds = evaluationRecords.stream()
                .map(er->er.getAsset().getId())
                .collect(Collectors.toSet());
        var relatedAssets = assetSource.stream()
                .filter(a->assetIds.stream().anyMatch(id->StringUtils.equals(id,a.getId())))
                .toList();
        AtomicInteger number = new AtomicInteger(1);
        //处理物理环境和物理安防措施分类相关资产信息
        var phyClassIds = List.of(AssetClassification.PHY_ENV.getId(),AssetClassification.PHY_SECURITY.getId());
        var phyAssets = relatedAssets.stream()
                .filter(a-> phyClassIds.stream().anyMatch(cid->StringUtils.equals(cid,a.getClassId())))
                .toList();
        var assetEvalResults = this.findAssetPhyUnitEvalResult(number,assetSource,phyAssets,evaluationRecords,unitTargets);

        //处理其他分类相关资产信息
        var otherAssets =  relatedAssets.stream()
                .filter(a-> phyClassIds.stream().noneMatch(cid->StringUtils.equals(cid,a.getClassId())))
                .toList();
        for(var otherAsset:otherAssets){
            assetEvalResults.add(AssetEvalResultDTO.builder()
                    .number(number.getAndIncrement())
                    .assetName(evaluationRecords.stream()
                            .filter(er->StringUtils.equals(er.getAsset().getId(),otherAsset.getId()))
                            .map(er->er.getAsset().getName())
                            .findFirst().orElse(""))
                    .targetEval(findAssetTargetEvalResult(otherAsset.getId(),evaluationRecords,unitTargets))
                    .build());
        }
        return assetEvalResults;
    }

    private List<AssetEvalResultDTO> findAssetPhyUnitEvalResult(AtomicInteger number, List<AssetDO> assetSources, List<AssetDO> relatedAssets,
                                                                List<EvaluationRecordDO> evaluationRecords,
                                                                List<SystemTargetDO> unitTargets){
        List<AssetEvalResultDTO> assetEvalResults = new ArrayList<>();
        var phyEnvAssets = assetSources.stream()
                .filter(a->StringUtils.equals(a.getClassId(),AssetClassification.PHY_ENV.getId()))
                .toList();
        for(var phyEnvAsset: phyEnvAssets){
            var phySecurity = AssetUtils.findPhySecurityByLocation(phyEnvAsset.getName(),relatedAssets);
            if(CollectionUtils.isEmpty(phySecurity)){
                continue;
            }
            assetEvalResults.add(getAssetPhyUnitEvalResult(number,phyEnvAsset,phySecurity,evaluationRecords,unitTargets));
        }
        return assetEvalResults;
    }

    private AssetEvalResultDTO getAssetPhyUnitEvalResult(AtomicInteger number,AssetDO phyEnvAsset,List<AssetDO> phySecurityAssets,
                                                         List<EvaluationRecordDO> evaluationRecords,
                                                         List<SystemTargetDO> unitTargets){
        var assetEvalResults = phySecurityAssets.stream()
                .flatMap(asset->findAssetTargetEvalResult(asset.getId(),evaluationRecords,unitTargets).stream())
                .toList();
        var phyEnvAssetEvalResult = unitTargets.stream()
                .map(unitTarget->AssetTargetEvalResultDTO.builder()
                        .targetId(unitTarget.getKmTargetId())
                        .targetName(unitTarget.getKmName())
                        .result(this.getAssetUnitEvalConclusion(unitTarget,assetEvalResults))
                        .build())
                .toList();

        return AssetEvalResultDTO.builder()
                .number(number.getAndIncrement())
                .assetName(AssetUtils.getAssetName(phyEnvAsset))
                .targetEval(phyEnvAssetEvalResult)
                .build();
    }

    private ReportEvaluationResult getAssetUnitEvalConclusion(SystemTargetDO unitTarget,List<AssetTargetEvalResultDTO> range){
        if(!unitTarget.getIsApply()
                || (CollectionUtils.isEmpty(range)|| range.size() == getAssetTargetConclusionCount(range,ReportEvaluationResult.NOT_APPLICABLE))){
            return ReportEvaluationResult.NOT_APPLICABLE;
        }
        var unitEvalResults = range.stream()
                .filter(er->StringUtils.equals(er.getTargetId(),unitTarget.getKmTargetId()))
                .toList();
        //判断是否全为不适用
        if(unitEvalResults.size() == getAssetTargetConclusionCount(unitEvalResults,ReportEvaluationResult.NOT_APPLICABLE)){
            return ReportEvaluationResult.NOT_APPLICABLE;
        }
        //从列表中排除不适用
        var evalResults = unitEvalResults.stream()
                .filter(er->er.getResult()!= ReportEvaluationResult.NOT_APPLICABLE)
                .collect(Collectors.toList());
        long count = evalResults.size();
        if(count == getAssetTargetConclusionCount(evalResults,ReportEvaluationResult.MATCH)){
            return ReportEvaluationResult.MATCH;
        }else if(count == getAssetTargetConclusionCount(evalResults,ReportEvaluationResult.NOT_MATCH)){
            return ReportEvaluationResult.NOT_MATCH;
        }else{
            return ReportEvaluationResult.PARTIALLY_MATCH;
        }
    }

    private NetCommunicationUnitEvalBO getNetCommunicationUnitEvaluation(List<SystemTargetDO> systemTargets){
        NetCommunicationUnitEvalBO data = new NetCommunicationUnitEvalBO();
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.NET_COMMUNICATION);
        if(Objects.isNull(layerTarget)){
            data.setTable(getNetCommunicationUnitEvalTableByEmpty());
            data.setConclusion(getNetCommunicationConclusionByEmpty());
            data.setResultAnalyze(getResultAnalyzeByEmpty());
            return data;
        }
        List<EvaluationRecordDO> evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        List<AssetEvalResultDTO> assetEvalResults = findAssetEvalResult(layerTarget,systemTargets,evaluationRecords);
        data.setTable(getNetCommunicationUnitEvalTable(assetEvalResults));
        data.setConclusion(NetCommunicationConclusionBO.builder()
                .identification(getUnitEvalConclusion(assetEvalResults,NetCommunicationUnitEvalTarget.IDENTIFICATION.getText(),systemTargets,layerTarget))
                .communication(getUnitEvalConclusion(assetEvalResults,NetCommunicationUnitEvalTarget.COMMUNICATION.getText(),systemTargets,layerTarget))
                .keyData(getUnitEvalConclusion(assetEvalResults,NetCommunicationUnitEvalTarget.KEY_DATA.getText(),systemTargets,layerTarget))
                .network(getUnitEvalConclusion(assetEvalResults,NetCommunicationUnitEvalTarget.NETWORK.getText(),systemTargets,layerTarget))
                .access(getUnitEvalConclusion(assetEvalResults,NetCommunicationUnitEvalTarget.ACCESS.getText(),systemTargets,layerTarget))
                .build());
        data.setResultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords));
        return data;
    }

    private DeviceComputeUnitEvalBO getDeviceComputeUnitEvaluation(List<SystemTargetDO> systemTargets){
        DeviceComputeUnitEvalBO data = new DeviceComputeUnitEvalBO();
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.DEVICE_COMPUTE);
        if(Objects.isNull(layerTarget)){
            data.setTable(getDeviceComputeUnitEvalTableByEmpty());
            data.setConclusion(getDeviceComputeConclusionByEmpty());
            data.setResultAnalyze(getResultAnalyzeByEmpty());
            return data;
        }
        List<EvaluationRecordDO> evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        List<AssetEvalResultDTO> assetEvalResults = findAssetEvalResult(layerTarget,systemTargets,evaluationRecords);
        data.setTable(getDeviceComputeUnitEvalTable(assetEvalResults));
        data.setConclusion(DeviceComputeConclusionBO.builder()
                .identification(getUnitEvalConclusion(assetEvalResults,DeviceComputeUnitEvalTarget.IDENTIFICATION.getText(),systemTargets,layerTarget))
                .remote(getUnitEvalConclusion(assetEvalResults,DeviceComputeUnitEvalTarget.REMOTE.getText(),systemTargets,layerTarget))
                .sysResource(getUnitEvalConclusion(assetEvalResults,DeviceComputeUnitEvalTarget.SYS_RESOURCE.getText(),systemTargets,layerTarget))
                .infoResource(getUnitEvalConclusion(assetEvalResults,DeviceComputeUnitEvalTarget.INFO_RESOURCE.getText(),systemTargets,layerTarget))
                .log(getUnitEvalConclusion(assetEvalResults,DeviceComputeUnitEvalTarget.LOG.getText(),systemTargets,layerTarget))
                .execute(getUnitEvalConclusion(assetEvalResults,DeviceComputeUnitEvalTarget.EXECUTE.getText(),systemTargets,layerTarget))
                .build());
        data.setResultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords));
        return data;
    }

    private AppDataUnitEvalBO getAppDataUnitEvaluation(List<SystemTargetDO> systemTargets){
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.APP_DATA);
        var evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        var summaryData = findAppDataUnitEvalSummaryData(layerTarget,systemTargets,evaluationRecords);
        var identificationData = findAppDataItemData(layerTarget,systemTargets,evaluationRecords,AppDataUnitEvalTarget.IDENTIFICATION);
        var appDataKeyData = findAppDataKeyData(layerTarget,systemTargets,evaluationRecords);
        var undeniableData = findAppDataItemData(layerTarget,systemTargets,evaluationRecords,AppDataUnitEvalTarget.UNDENIABLE);
        return AppDataUnitEvalBO.builder()
                .table(getAppDataUnitEvalTable(summaryData))
                .conclusion(getAppDataConclusion(summaryData,systemTargets,layerTarget))
                .identificationTable(getAppDataItemTable(identificationData))
                .identificationConclusion(getAppDataItemConclusion(identificationData,systemTargets,layerTarget,AppDataUnitEvalTarget.IDENTIFICATION))
                .keyDataTable(getAppDataKeyDataTable(appDataKeyData))
                .keyDataConclusion(getAppDataKeyDataConclusion(appDataKeyData,systemTargets,layerTarget))
                .undeniableTable(getAppDataItemTable(undeniableData))
                .undeniableConclusion(getAppDataItemConclusion(undeniableData,systemTargets,layerTarget,AppDataUnitEvalTarget.UNDENIABLE))
                .resultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords))
                .build();
    }

    private List<AssetEvalResultDTO> findAppDataUnitEvalSummaryData(SystemTargetDO layerTarget,List<SystemTargetDO> systemTargets,
                                                                    List<EvaluationRecordDO> evaluationRecords){
        List<SystemTargetDO> unitTargets = findUnitTargets(systemTargets,layerTarget.getKmTargetId());
        if(CollectionUtils.isEmpty(evaluationRecords)){
            return Collections.emptyList();
        }
        var assetSource = this.assetRepository.findAllBySystemId(layerTarget.getSystemId());
        //获取测评对象ID列表
        Set<String> assetIds = evaluationRecords.stream()
                .map(er->er.getAsset().getId())
                .collect(Collectors.toSet());
        var relatedAssets = assetSource.stream()
                .filter(a->assetIds.stream().anyMatch(id->StringUtils.equals(id,a.getId())))
                .toList();
        AtomicInteger number = new AtomicInteger(1);
        //处理关键业务应用和重要数据分类相关资产信息
        var keyClassIds = List.of(AssetClassification.KEY_BUSINESS.getId(),
                AssetClassification.SUB_BUSINESS.getId(),
                AssetClassification.KEY_DATA.getId());
        var keyAssets = relatedAssets.stream()
                .filter(a-> keyClassIds.stream().anyMatch(cid->StringUtils.equals(cid,a.getClassId())))
                .toList();
        return this.findAssetKeyUnitEvalResult(number,assetSource,keyAssets,evaluationRecords,unitTargets);
    }

    private List<AssetEvalResultDTO>  findAssetKeyUnitEvalResult(AtomicInteger number,List<AssetDO> assetSources,List<AssetDO> relatedAssets,
                                                                 List<EvaluationRecordDO> evaluationRecords,
                                                                 List<SystemTargetDO> unitTargets){
        List<AssetEvalResultDTO> assetEvalResults = new ArrayList<>();
        var keyBusinessAssets = assetSources.stream()
                .filter(a->StringUtils.equals(a.getClassId(),AssetClassification.KEY_BUSINESS.getId()))
                .toList();
        for(var keyBusiness: keyBusinessAssets){
            var keyAssets = new ArrayList<>(AssetUtils.findSubBusinessByOwnedApp(keyBusiness.getName(),relatedAssets));
            keyAssets.addAll(AssetUtils.findKeyDataByOwnedApp(keyBusiness.getName(),relatedAssets));
            if(CollectionUtils.isEmpty(keyAssets)){
                continue;
            }
            assetEvalResults.add(getAssetKeyUnitEvalResult(number,keyBusiness,keyAssets,evaluationRecords,unitTargets));
        }
        return assetEvalResults;
    }

    private AssetEvalResultDTO  getAssetKeyUnitEvalResult(AtomicInteger number,AssetDO keyBusiness,List<AssetDO> keyAssets,
                                                          List<EvaluationRecordDO> evaluationRecords,
                                                          List<SystemTargetDO> unitTargets){
        var assetEvalResults = keyAssets.stream()
                .flatMap(asset->findAssetTargetEvalResult(asset.getId(),evaluationRecords,unitTargets).stream())
                .toList();
        var keyAssetEvalResult = unitTargets.stream()
                .map(unitTarget->AssetTargetEvalResultDTO.builder()
                        .targetId(unitTarget.getKmTargetId())
                        .targetName(unitTarget.getKmName())
                        .result(this.getAssetUnitEvalConclusion(unitTarget,assetEvalResults))
                        .build())
                .toList();
        return AssetEvalResultDTO.builder()
                .number(number.getAndIncrement())
                .assetName(AssetUtils.getAssetName(keyBusiness))
                .targetEval(keyAssetEvalResult)
                .build();
    }

    private List<UnitEvalReportBO> getAppDataUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getAppDataUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(8);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(AppDataUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private AppDataConclusionBO getAppDataConclusion(List<AssetEvalResultDTO> assetEvalResults,List<SystemTargetDO> systemTargets,
                                                     SystemTargetDO layerTarget){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getAppDataConclusionByEmpty();
        }
        return AppDataConclusionBO.builder()
                .identification(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.IDENTIFICATION.getText(),systemTargets,layerTarget))
                .control(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.CONTROL.getText(),systemTargets,layerTarget))
                .keyData(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.KEY_DATA.getText(),systemTargets,layerTarget))
                .transportSecret(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.TRANSPORT_SECRET.getText(),systemTargets,layerTarget))
                .storageSecret(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.STORAGE_SECRET.getText(),systemTargets,layerTarget))
                .transportCompleted(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.TRANSPORT_COMPLETED.getText(),systemTargets,layerTarget))
                .storageCompleted(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.STORAGE_COMPLETED.getText(),systemTargets,layerTarget))
                .undeniable(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.UNDENIABLE.getText(),systemTargets,layerTarget))
                .build();
    }

    private List<AssetEvalResultDTO> findAppDataItemData(SystemTargetDO layerTarget,List<SystemTargetDO> systemTargets,
                                                         List<EvaluationRecordDO> evaluationRecords,AppDataUnitEvalTarget layer){
        //获取指定的层面指标测评指标
        SystemTargetDO unitTarget = systemTargets.stream()
                .filter(st->StringUtils.equals(st.getKmParentId(),layerTarget.getKmTargetId())
                        && StringUtils.equals(st.getKmName(),layer.getText()))
                .findFirst().orElse(null);
        if(CollectionUtils.isEmpty(evaluationRecords) || Objects.isNull(unitTarget)){
            return Collections.emptyList();
        }
        Set<String> classIds = Stream.of(AssetClassification.KEY_BUSINESS.getId(),
                        AssetClassification.KEY_DATA.getId(),
                        AssetClassification.SUB_BUSINESS.getId())
                .collect(Collectors.toSet());
        //获取关键业务应用、重要数据类型的测评对象ID列表
        Set<String> assetIds = evaluationRecords.stream()
                .filter(er-> classIds.stream().anyMatch(cid->StringUtils.equals(cid,er.getAsset().getClassId()))
                        && StringUtils.equals(er.getUnitTargetId(),unitTarget.getKmTargetId()))
                .sorted(Comparator.comparing((a)->Objects.nonNull(a.getAsset().getQuoteAssetId())?a.getAsset().getQuoteAssetId():a.getAsset().getClassId()))
                .map(er->er.getAsset().getId())
                .collect(Collectors.toSet());
        List<AssetEvalResultDTO> assetEvalResults = new ArrayList<>();
        int number = 1;
        for(String assetId:assetIds){
            EvaluationRecordDO recordDO = evaluationRecords.stream()
                    .filter(er ->StringUtils.equals(er.getAsset().getId(),assetId)
                            && StringUtils.equals(er.getUnitTargetId(),unitTarget.getKmTargetId()))
                    .findFirst().orElse(null);
            if(Objects.isNull(recordDO)){
                continue;
            }
            assetEvalResults.add(AssetEvalResultDTO.builder()
                    .number(number)
                    .assetName(AssetUtils.getAssetName(recordDO.getAsset()))
                    .targetEval(Collections.singletonList(AssetTargetEvalResultDTO.builder()
                            .targetId(recordDO.getUnitTargetId())
                            .targetName(getUnitTargetName(recordDO.getUnitTargetId(),systemTargets))
                            .result(ReportEvaluationResult.fromConclusion(recordDO.getConclusion().getConclusion()))
                            .build()))
                    .build());
            number++;
        }
        return assetEvalResults;
    }

    private List<AppDataItemReportBO> getAppDataItemTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getAppDataItemTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    var data = AppDataItemReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .name(er.getAssetName())
                            .build();
                    er.getTargetEval()
                            .stream()
                            .findFirst()
                            .ifPresent(ter-> data.setResult(ter.getResult().getTag()));
                    return data;
                })
                .toList();
    }

    private AppDataItemConclusionBO getAppDataItemConclusion(List<AssetEvalResultDTO> assetEvalResults,List<SystemTargetDO> systemTargets,
                                                             SystemTargetDO layerTarget,AppDataUnitEvalTarget unitTarget){
        return AppDataItemConclusionBO.builder()
                .result(getUnitEvalConclusion(assetEvalResults,unitTarget.getText(),systemTargets,layerTarget))
                .build();
    }

    private List<AssetEvalResultDTO> findAppDataKeyData(SystemTargetDO layerTarget,List<SystemTargetDO> systemTargets,
                                                        List<EvaluationRecordDO> evaluationRecords){
        //获取传输机密性、存储机密性、传输完整性、存储完整性测评指标
        List<String> unitTargetNames = Stream.of(AppDataUnitEvalTarget.TRANSPORT_SECRET,AppDataUnitEvalTarget.STORAGE_SECRET,
                        AppDataUnitEvalTarget.TRANSPORT_COMPLETED,AppDataUnitEvalTarget.STORAGE_COMPLETED)
                .map(AppDataUnitEvalTarget::getText)
                .toList();
        List<SystemTargetDO> unitTargets = systemTargets.stream()
                .filter(st->StringUtils.equals(st.getKmParentId(),layerTarget.getKmTargetId())
                        && unitTargetNames.stream().anyMatch(utn->StringUtils.equals(st.getKmName(),utn)))
                .collect(Collectors.toList());
        if(CollectionUtils.isEmpty(evaluationRecords) || CollectionUtils.isEmpty(unitTargets)){
            return Collections.emptyList();
        }
        Set<String> classIds = Stream.of(AssetClassification.KEY_BUSINESS.getId(),
                AssetClassification.SUB_BUSINESS.getId(),
                AssetClassification.KEY_DATA.getId()).collect(Collectors.toSet());
        //获取关键业务应用、重要数据类型的测评对象ID列表
        Set<String> assetIds = evaluationRecords.stream()
                .filter(er-> classIds.stream().anyMatch(cid->StringUtils.equals(cid,er.getAsset().getClassId()))
                        && unitTargetNames.stream().anyMatch(utn->StringUtils.equals(getUnitTargetName(er.getUnitTargetId(),systemTargets),utn)))
                .sorted(Comparator.comparing((a)->Objects.nonNull(a.getAsset().getQuoteAssetId())?a.getAsset().getQuoteAssetId():a.getAsset().getClassId()))
                .map(er->er.getAsset().getId())
                .collect(Collectors.toSet());
        List<AssetEvalResultDTO> assetEvalResults = new ArrayList<>();
        int number = 1;
        for(String assetId:assetIds){
            AssetDO assetDO = evaluationRecords.stream()
                    .map(EvaluationRecordDO::getAsset)
                    .filter(asset ->StringUtils.equals(asset.getId(),assetId))
                    .findFirst().orElse(null);
            if(Objects.isNull(assetDO)){
                continue;
            }
            assetEvalResults.add(AssetEvalResultDTO.builder()
                    .number(number)
                    .assetName(AssetUtils.getAssetName(assetDO))
                    .targetEval(findAppDataKeyTargetEvalResult(assetDO,evaluationRecords,unitTargets))
                    .build());
            number++;
        }
        return assetEvalResults;
    }

    private List<AssetTargetEvalResultDTO> findAppDataKeyTargetEvalResult(AssetDO assetDO,List<EvaluationRecordDO> evaluationRecords,
                                                                          List<SystemTargetDO> unitTargets){
        List<AssetTargetEvalResultDTO> assetTargetEvalResults = new ArrayList<>();
        //关联的重要数据资产，测评指标符合情况
        for(SystemTargetDO unitTarget:unitTargets){
            List<EvaluationRecordDO> keyDataRecords = evaluationRecords.stream()
                    .filter(er->StringUtils.equals(er.getUnitTargetId(),unitTarget.getKmTargetId())
                            && StringUtils.contains(er.getAsset().getId(),assetDO.getId()))
                    .collect(Collectors.toList());
            if(CollectionUtils.isEmpty(keyDataRecords)){
                assetTargetEvalResults.add(AssetTargetEvalResultDTO.builder()
                        .targetId(unitTarget.getKmTargetId())
                        .targetName(unitTarget.getKmName())
                        .result(ReportEvaluationResult.NOT_APPLICABLE)
                        .build());
            }else{
                assetTargetEvalResults.add(AssetTargetEvalResultDTO.builder()
                        .targetId(unitTarget.getKmTargetId())
                        .targetName(unitTarget.getKmName())
                        .result(ReportEvaluationResult.fromConclusion(CalculateUtils.getUnitEvalConclusion(keyDataRecords).getConclusion()))
                        .build());
            }
        }
        return assetTargetEvalResults;
    }

    private List<AppKeyDataReportBO> getAppDataKeyDataTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getAppDataKeyDataTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(4);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(AppDataUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return AppKeyDataReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .data(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private AppDataKeyDataConclusionBO getAppDataKeyDataConclusion(List<AssetEvalResultDTO> assetEvalResults,List<SystemTargetDO> systemTargets,
                                                                   SystemTargetDO layerTarget){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getAppDataKeyDataConclusionByEmpty();
        }
        return AppDataKeyDataConclusionBO.builder()
                .transportSecret(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.TRANSPORT_SECRET.getText(),systemTargets,layerTarget))
                .storageSecret(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.STORAGE_SECRET.getText(),systemTargets,layerTarget))
                .transportCompleted(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.TRANSPORT_COMPLETED.getText(),systemTargets,layerTarget))
                .storageCompleted(getUnitEvalConclusion(assetEvalResults,AppDataUnitEvalTarget.STORAGE_COMPLETED.getText(),systemTargets,layerTarget))
                .build();
    }

    private ManageSystemUnitEvalBO getManageSystemUnitEvaluation(SystemDO systemDO, List<SystemTargetDO> systemTargets){
        ManageSystemUnitEvalBO data = new ManageSystemUnitEvalBO();
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.MANAGE_SYSTEM);
        if(Objects.isNull(layerTarget)){
            data.setTable(getManageSystemUnitEvalTableByEmpty());
            data.setConclusion(getManageSystemConclusionByEmpty());
            data.setResultAnalyze(getResultAnalyzeByEmpty());
            return data;
        }
        List<EvaluationRecordDO> evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        List<AssetEvalResultDTO> assetEvalResults = findAssetEvalResult(layerTarget,systemTargets,evaluationRecords);
        data.setTable(getManageSystemUnitEvalTable(assetEvalResults));
        data.setConclusion(ManageSystemConclusionBO.builder()
                .pwdManage(getUnitEvalConclusion(assetEvalResults,ManageSystemUnitEvalTarget.PWD_MANAGE.getText(),systemTargets,layerTarget))
                .keyManage(getUnitEvalConclusion(assetEvalResults,ManageSystemUnitEvalTarget.KEY_MANAGE.getText(),systemTargets,layerTarget))
                .addOpt(getUnitEvalConclusion(assetEvalResults,ManageSystemUnitEvalTarget.ADD_OPT.getText(),systemTargets,layerTarget))
                .editSafe(getUnitEvalConclusion(assetEvalResults,ManageSystemUnitEvalTarget.EDIT_SAFE.getText(),systemTargets,layerTarget))
                .clearProcess(getUnitEvalConclusion(assetEvalResults,ManageSystemUnitEvalTarget.CLEAR_PROCESS.getText(),systemTargets,layerTarget))
                .recordKeep(getUnitEvalConclusion(assetEvalResults,ManageSystemUnitEvalTarget.RECORD_KEEP.getText(),systemTargets,layerTarget))
                .build());
        data.setResultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords));
        return data;
    }

    private PersonnelManageUnitEvalBO getPersonnelManageUnitEvaluation(SystemDO systemDO,List<SystemTargetDO> systemTargets){
        PersonnelManageUnitEvalBO data = new PersonnelManageUnitEvalBO();
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.PERSONNEL_MANAGE);
        if(Objects.isNull(layerTarget)){
            data.setTable(getPersonnelManageUnitEvalTableByEmpty());
            data.setConclusion(getPersonnelManageConclusionByEmpty());
            data.setResultAnalyze(getResultAnalyzeByEmpty());
            return data;
        }
        List<EvaluationRecordDO> evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        List<AssetEvalResultDTO> assetEvalResults = findAssetEvalResult(layerTarget,systemTargets,evaluationRecords);
        data.setTable(getPersonnelManageUnitEvalTable(assetEvalResults));
        data.setConclusion(PersonnelManageConclusionBO.builder()
                .pwdManage(getUnitEvalConclusion(assetEvalResults,PersonnelManageUnitEvalTarget.PWD_MANAGE.getText(),systemTargets,layerTarget))
                .buildPwd(getUnitEvalConclusion(assetEvalResults,PersonnelManageUnitEvalTarget.BUILD_PWD.getText(),systemTargets,layerTarget))
                .buildPersonnel(getUnitEvalConclusion(assetEvalResults,PersonnelManageUnitEvalTarget.BUILD_PERSONNEL.getText(),systemTargets,layerTarget))
                .regularAssessment(getUnitEvalConclusion(assetEvalResults,PersonnelManageUnitEvalTarget.REGULAR_ASSESSMENT.getText(),systemTargets,layerTarget))
                .buildSecure(getUnitEvalConclusion(assetEvalResults,PersonnelManageUnitEvalTarget.BUILD_SECURE.getText(),systemTargets,layerTarget))
                .build());
        data.setResultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords));
        return data;
    }

    private BuildRunningUnitEvalBO getBuildRunningUnitEvaluation(SystemDO systemDO,List<SystemTargetDO> systemTargets){
        BuildRunningUnitEvalBO data = new BuildRunningUnitEvalBO();
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.BUILD_RUNNING);
        if(Objects.isNull(layerTarget)){
            data.setTable(getBuildRunningUnitEvalTableByEmpty());
            data.setConclusion(getBuildRunningConclusionByEmpty());
            data.setResultAnalyze(getResultAnalyzeByEmpty());
            return data;
        }
        List<EvaluationRecordDO> evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        List<AssetEvalResultDTO> assetEvalResults = findAssetEvalResult(layerTarget,systemTargets,evaluationRecords);
        data.setTable(getBuildRunningUnitEvalTable(assetEvalResults));
        data.setConclusion(BuildRunningConclusionBO.builder()
                .buildPwd(getUnitEvalConclusion(assetEvalResults,BuildRunningUnitEvalTarget.BUILD_PWD.getText(),systemTargets,layerTarget))
                .buildKey(getUnitEvalConclusion(assetEvalResults,BuildRunningUnitEvalTarget.BUILD_KEY.getText(),systemTargets,layerTarget))
                .buildImplement(getUnitEvalConclusion(assetEvalResults,BuildRunningUnitEvalTarget.BUILD_IMPLEMENT.getText(),systemTargets,layerTarget))
                .runSecure(getUnitEvalConclusion(assetEvalResults,BuildRunningUnitEvalTarget.RUN_SECURE.getText(),systemTargets,layerTarget))
                .regularDrills(getUnitEvalConclusion(assetEvalResults,BuildRunningUnitEvalTarget.REGULAR_DRILLS.getText(),systemTargets,layerTarget))
                .build());
        data.setResultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords));
        return data;
    }

    private HandlingUnitEvalBO getHandlingUnitEvaluation(SystemDO systemDO,List<SystemTargetDO> systemTargets){
        HandlingUnitEvalBO data = new HandlingUnitEvalBO();
        SystemTargetDO layerTarget = findLayerTarget(systemTargets,LayerTarget.EMERGENCY_HANDLING);
        if(Objects.isNull(layerTarget)){
            data.setTable(getHandlingUnitEvalTableByEmpty());
            data.setConclusion(getHandlingConclusionByEmpty());
            data.setResultAnalyze(getResultAnalyzeByEmpty());
            return data;
        }
        List<EvaluationRecordDO> evaluationRecords = evaluationRecordRepository.findAllBySystemIdAndLayerTargetId(layerTarget.getSystemId()
                ,layerTarget.getKmTargetId());
        List<AssetEvalResultDTO> assetEvalResults = findAssetEvalResult(layerTarget,systemTargets,evaluationRecords);
        data.setTable(getHandlingUnitEvalTable(assetEvalResults));
        data.setConclusion(HandlingConclusionBO.builder()
                .emergency(getUnitEvalConclusion(assetEvalResults,HandlingUnitEvalTarget.EMERGENCY.getText(),systemTargets,layerTarget))
                .event(getUnitEvalConclusion(assetEvalResults,HandlingUnitEvalTarget.EVENT.getText(),systemTargets,layerTarget))
                .disposal(getUnitEvalConclusion(assetEvalResults,HandlingUnitEvalTarget.DISPOSAL.getText(),systemTargets,layerTarget))
                .build());
        data.setResultAnalyze(getResultAnalyze(layerTarget,systemTargets,evaluationRecords));
        return data;
    }

    private List<UnitEvalReportBO> getPhyUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getPhyUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(3);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(PhyEnvUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private List<UnitEvalReportBO> getNetCommunicationUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getNetCommunicationUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(5);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(NetCommunicationUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private List<UnitEvalReportBO> getDeviceComputeUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getDeviceComputeUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(5);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(DeviceComputeUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }


    private List<UnitEvalReportBO> getManageSystemUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getManageSystemUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(5);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(ManageSystemUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private List<UnitEvalReportBO> getPersonnelManageUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getPersonnelManageUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(5);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(PersonnelManageUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private List<UnitEvalReportBO> getBuildRunningUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getBuildRunningUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(5);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(BuildRunningUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private List<UnitEvalReportBO> getHandlingUnitEvalTable(List<AssetEvalResultDTO> assetEvalResults){
        if(CollectionUtils.isEmpty(assetEvalResults)){
            return getHandlingUnitEvalTableByEmpty();
        }
        return assetEvalResults.stream()
                .map(er->{
                    Map<String,String> data=new HashMap<>(5);
                    for(AssetTargetEvalResultDTO ter:er.getTargetEval()){
                        data.put(HandlingUnitEvalTarget.fromText(ter.getTargetName()).getValue(),ter.getResult().getTag());
                    }
                    return UnitEvalReportBO.builder()
                            .number(DataUtils.toString(er.getNumber()))
                            .asset(er.getAssetName())
                            .unitResult(data)
                            .build();
                })
                .toList();
    }

    private List<UnitEvalReportBO> getPhyUnitEvalTableByEmpty(){
        return List.of(UnitEvalReportBO.builder()
                        .number("")
                        .asset("")
                        .unitResult(new HashMap<>())
                .build());
    }

    private PhyEnvConclusionBO getPhyEnvConclusionByEmpty(){
        return PhyEnvConclusionBO.builder()
                .identification("")
                .electronic("")
                .video("")
                .build();
    }

    private List<UnitEvalReportBO> getNetCommunicationUnitEvalTableByEmpty(){
        Map<String,String> data1=new HashMap<>(5);
        data1.put(NetCommunicationUnitEvalTarget.IDENTIFICATION.getValue(), "");
        data1.put(NetCommunicationUnitEvalTarget.COMMUNICATION.getValue(), "");
        data1.put(NetCommunicationUnitEvalTarget.KEY_DATA.getValue(), "");
        data1.put(NetCommunicationUnitEvalTarget.NETWORK.getValue(), "");
        data1.put(NetCommunicationUnitEvalTarget.ACCESS.getValue(), "");
        return List.of(UnitEvalReportBO.builder()
                        .number("")
                        .asset("")
                        .unitResult(data1)
                .build());
    }

    private NetCommunicationConclusionBO getNetCommunicationConclusionByEmpty(){
        return NetCommunicationConclusionBO.builder()
                .identification("")
                .communication("")
                .keyData("")
                .network("")
                .access("")
                .build();
    }

    private List<UnitEvalReportBO> getDeviceComputeUnitEvalTableByEmpty(){
        Map<String,String> data1=new HashMap<>(6);
        data1.put(DeviceComputeUnitEvalTarget.IDENTIFICATION.getValue(), "");
        data1.put(DeviceComputeUnitEvalTarget.REMOTE.getValue(), "");
        data1.put(DeviceComputeUnitEvalTarget.SYS_RESOURCE.getValue(), "");
        data1.put(DeviceComputeUnitEvalTarget.INFO_RESOURCE.getValue(), "");
        data1.put(DeviceComputeUnitEvalTarget.LOG.getValue(), "");
        data1.put(DeviceComputeUnitEvalTarget.EXECUTE.getValue(), "");
        return List.of(UnitEvalReportBO.builder()
                .number("")
                .asset("")
                .unitResult(data1)
                .build());
    }

    private DeviceComputeConclusionBO getDeviceComputeConclusionByEmpty(){
        return DeviceComputeConclusionBO.builder()
                .identification("")
                .remote("")
                .sysResource("")
                .infoResource("")
                .log("")
                .execute("")
                .build();
    }

    private List<UnitEvalReportBO> getAppDataUnitEvalTableByEmpty(){
        Map<String,String> data1=new HashMap<>(8);
        data1.put(AppDataUnitEvalTarget.IDENTIFICATION.getValue(), "");
        data1.put(AppDataUnitEvalTarget.CONTROL.getValue(), "");
        data1.put(AppDataUnitEvalTarget.KEY_DATA.getValue(), "");
        data1.put(AppDataUnitEvalTarget.TRANSPORT_SECRET.getValue(), "");
        data1.put(AppDataUnitEvalTarget.STORAGE_SECRET.getValue(), "");
        data1.put(AppDataUnitEvalTarget.TRANSPORT_COMPLETED.getValue(), "");
        data1.put(AppDataUnitEvalTarget.STORAGE_COMPLETED.getValue(), "");
        data1.put(AppDataUnitEvalTarget.UNDENIABLE.getValue(), "");
        return List.of(UnitEvalReportBO.builder()
                .number("")
                .asset("")
                .unitResult(data1)
                .build());
    }

    private AppDataConclusionBO getAppDataConclusionByEmpty(){
        return AppDataConclusionBO.builder()
                .identification("")
                .control("")
                .keyData("")
                .transportSecret("")
                .storageSecret("")
                .transportCompleted("")
                .storageCompleted("")
                .undeniable("")
                .build();
    }

    private List<UnitEvalReportBO> getManageSystemUnitEvalTableByEmpty(){
        Map<String,String> data1=new HashMap<>(6);
        data1.put(ManageSystemUnitEvalTarget.PWD_MANAGE.getValue(), "");
        data1.put(ManageSystemUnitEvalTarget.KEY_MANAGE.getValue(), "");
        data1.put(ManageSystemUnitEvalTarget.ADD_OPT.getValue(), "");
        data1.put(ManageSystemUnitEvalTarget.EDIT_SAFE.getValue(), "");
        data1.put(ManageSystemUnitEvalTarget.CLEAR_PROCESS.getValue(), "");
        data1.put(ManageSystemUnitEvalTarget.RECORD_KEEP.getValue(), "");
        return List.of(UnitEvalReportBO.builder()
                .number("")
                .asset("")
                .unitResult(data1)
                .build());
    }

    private ManageSystemConclusionBO getManageSystemConclusionByEmpty(){
        return ManageSystemConclusionBO.builder()
                .pwdManage("")
                .keyManage("")
                .addOpt("")
                .editSafe("")
                .clearProcess("")
                .recordKeep("")
                .build();
    }

    private List<UnitEvalReportBO> getPersonnelManageUnitEvalTableByEmpty(){
        Map<String,String> data1=new HashMap<>(5);
        data1.put(PersonnelManageUnitEvalTarget.PWD_MANAGE.getValue(), "");
        data1.put(PersonnelManageUnitEvalTarget.BUILD_PWD.getValue(), "");
        data1.put(PersonnelManageUnitEvalTarget.BUILD_PERSONNEL.getValue(), "");
        data1.put(PersonnelManageUnitEvalTarget.REGULAR_ASSESSMENT.getValue(), "");
        data1.put(PersonnelManageUnitEvalTarget.BUILD_SECURE.getValue(), "");
        return List.of(UnitEvalReportBO.builder()
                .number("")
                .asset("")
                .unitResult(data1)
                .build());
    }

    private PersonnelManageConclusionBO getPersonnelManageConclusionByEmpty(){
        return PersonnelManageConclusionBO.builder()
                .pwdManage("")
                .buildPwd("")
                .buildPersonnel("")
                .regularAssessment("")
                .buildSecure("")
                .build();
    }

    private List<UnitEvalReportBO> getBuildRunningUnitEvalTableByEmpty(){
        Map<String,String> data1=new HashMap<>(5);
        data1.put(BuildRunningUnitEvalTarget.BUILD_PWD.getValue(), "");
        data1.put(BuildRunningUnitEvalTarget.BUILD_KEY.getValue(), "");
        data1.put(BuildRunningUnitEvalTarget.BUILD_IMPLEMENT.getValue(), "");
        data1.put(BuildRunningUnitEvalTarget.RUN_SECURE.getValue(), "");
        data1.put(BuildRunningUnitEvalTarget.REGULAR_DRILLS.getValue(), "");
        return List.of(UnitEvalReportBO.builder()
                .number("")
                .asset("")
                .unitResult(data1)
                .build());
    }

    private BuildRunningConclusionBO getBuildRunningConclusionByEmpty(){
        return BuildRunningConclusionBO.builder()
                .buildPwd("")
                .buildKey("")
                .buildImplement("")
                .runSecure("")
                .regularDrills("")
                .build();
    }

    private List<UnitEvalReportBO> getHandlingUnitEvalTableByEmpty(){
        Map<String,String> data1=new HashMap<>(3);
        data1.put(HandlingUnitEvalTarget.EMERGENCY.getValue(), "");
        data1.put(HandlingUnitEvalTarget.EVENT.getValue(), "");
        data1.put(HandlingUnitEvalTarget.DISPOSAL.getValue(), "");
        return List.of(UnitEvalReportBO.builder()
                .number("")
                .asset("")
                .unitResult(data1)
                .build());
    }

    private HandlingConclusionBO getHandlingConclusionByEmpty(){
        return HandlingConclusionBO.builder()
                .emergency("")
                .event("")
                .disposal("")
                .build();
    }

    private List<AppDataItemReportBO> getAppDataItemTableByEmpty(){
        return List.of(AppDataItemReportBO.builder()
                .number("")
                .name("")
                .result("")
                .build());
    }

    private List<AppKeyDataReportBO> getAppDataKeyDataTableByEmpty(){
        Map<String,String> data1=new HashMap<>(4);
        data1.put(AppDataUnitEvalTarget.TRANSPORT_SECRET.getValue(), "");
        data1.put(AppDataUnitEvalTarget.STORAGE_SECRET.getValue(), "");
        data1.put(AppDataUnitEvalTarget.TRANSPORT_COMPLETED.getValue(), "");
        data1.put(AppDataUnitEvalTarget.STORAGE_COMPLETED.getValue(), "");
        return List.of(AppKeyDataReportBO.builder()
                .number("")
                .data("")
                .unitResult(data1)
                .build());
    }

    private AppDataKeyDataConclusionBO getAppDataKeyDataConclusionByEmpty(){
        return  AppDataKeyDataConclusionBO.builder()
                .transportSecret("")
                .storageSecret("")
                .transportCompleted("")
                .storageCompleted("")
                .build();
    }

    private AppDataItemConclusionBO getAppDataItemConclusionByEmpty(){
        return AppDataItemConclusionBO.builder()
                .result("")
                .build();
    }

    private String getResultAnalyzeByEmpty(){
        return getResultAnalyzeContent(
                "1）单元指标名称",
                "该单元指标测评结果的描述信息。",
                EvaluationConclusion.NOT_MATCH);
    }

    private String getResultAnalyzeContent(String targetName, String analysisDesc, EvaluationConclusion conclusion) {
        String endDesc = String.format("因此该测评单元为%s。", conclusion.getName());
        return Stream.of(targetName, analysisDesc, endDesc)
                .map(StringUtils::trim)
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.joining("\n"));

    }


}
